package com.hzw.saas.web.storage.controller;

import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.hzw.saas.api.storage.ISysResourceService;
import com.hzw.saas.api.storage.bo.SysResourceBO;
import com.hzw.saas.api.storage.bo.SysResourceDataBO;
import com.hzw.saas.common.config.annotation.SysLog;
import com.hzw.saas.common.config.exception.DefaultSaasException;
import com.hzw.saas.common.config.util.AssertUtil;
import com.hzw.saas.common.security.utils.SecurityUtils;
import com.hzw.saas.common.util.HttpContextUtils;
import com.hzw.saas.web.storage.param.SysResourceGetParam;
import com.hzw.saas.web.storage.param.SysResourcePostParam;
import cn.hutool.extra.servlet.ServletUtil;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import ma.glasnost.orika.MapperFacade;

/**
 * @author zzl
 * @since 03/01/2021
 */
@Controller
@RequestMapping("/sys")
@Slf4j
@RequiredArgsConstructor
@Api(tags = "资源管理/系统资源")
@Validated
public class SysResourceController {

    private final ISysResourceService resourceService;

    @GetMapping("/resource/exists")
    @SysLog
    @ApiOperation(value = "查询资源是否存在", notes = "查询资源是否存在")
    @ApiResponses({
        @ApiResponse(code = 200, message = "true-存在，false-不存在", response = Integer.class)
    })
    public ResponseEntity<Boolean> exists(@Validated SysResourceGetParam param) {
        boolean exists = this.resourceService.exists(SecurityUtils.getUser().getUserId(), param.getName());
        return ResponseEntity.ok(exists);
    }

    @PostMapping(value = "/resource", consumes = {"multipart/form-data"})
    @SysLog
    @ApiOperation(value = "上传资源", notes = "上传资源")
    @ApiResponses({
        @ApiResponse(code = 200, message = "上传成功，返回资源ID"),
        @ApiResponse(code = 400, message = "请求参数异常"),
        @ApiResponse(code = 415, message = "文件类型不支持"),
        @ApiResponse(code = 500, message = "服务器内部错误")
    })
    @ApiOperationSort(6)
    public ResponseEntity<String> save(@Validated SysResourcePostParam param, HttpServletRequest request) {
        // 判断请求类型
        boolean multipart = ServletUtil.isMultipart(request);
        AssertUtil.assertThrow("上传失败，请求参数异常，请使用multipart/form-data类型上传", !multipart);
        SysResourceDataBO sysResourceDataBO = new SysResourceDataBO();
        sysResourceDataBO.setFile(param.getFile());
        sysResourceDataBO.setCreatorId(SecurityUtils.getUser().getUserId());
        sysResourceDataBO.setName(param.getName());
        SysResourceBO result = this.resourceService.add(sysResourceDataBO);
        return ResponseEntity.ok(result.getFileId());
    }

    @GetMapping(value = "/resource")
    @SysLog(operation = "下载资源", mode = 3)
    @ApiOperation(value = "下载资源", notes = "下载资源")
    @ApiResponses({
        @ApiResponse(code = 200, message = "请求成功"),
        @ApiResponse(code = 400, message = "请求参数或请求类型异常"),
        @ApiResponse(code = 500, message = "服务器内部错误")
    })
    public void download(@Validated SysResourceGetParam param, HttpServletRequest request, HttpServletResponse response) {

        try (OutputStream fos = response.getOutputStream()) {
            SysResourceBO sysResourceBO = this.resourceService.get(SecurityUtils.getUser().getUserId(), param.getName());
            AssertUtil.assertThrow("文件不存在", sysResourceBO == null);
            HttpContextUtils.setFileDownloadHeader(request, response, param.getName(), sysResourceBO.getLength());
            resourceService.download(SecurityUtils.getUser().getUserId(), param.getName(), fos);
            response.flushBuffer();
            log.debug("download file over...");
        } catch (IOException e) {
            log.error("download error", e);
            throw DefaultSaasException.build("下载文件异常");
        }
    }


}
